<?php

class ToolbaseI18N {

  static protected
    $instance   = null;
    
  protected $messages = array();
  protected $filename = null;
  protected $culture = 'en';

  protected function __construct( $filename = null )
  {
    if( is_null( $filename ) ) {
        $filename = sfConfig::get( 'sf_app_i18n_dir' ) . '/ToolbaseMessages.i18n.php';
    }
    
    if( !file_exists( $filename ) ) {
        throw new InvalidArgumentException( sprintf( 'Invalid messages file specified: %s', $filename ) );
    }
    
    $this->filename = $filename;
    
    include( $filename );
    
    $this->messages = $messages;
    
    if( sfContext::hasInstance() ) {
        sfContext::getInstance()->getEventDispatcher()->connect('user.change_culture', array($this, 'listenToChangeCultureEvent'));
    }
    
  }

  /**
   * Retrieves the singleton instance of this class.
   *
   * @param  string $cacheFile  The file path to save the cache
   *
   * @return ToolbaseI18N
   */
  static public function getInstance( $filename = null )
  {
    if (!isset(self::$instance))
    {
      self::$instance = new self( $filename );
    }

    return self::$instance;
  }
  
  public function ___( $text, $args ) {
        
        if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled')) {
                $timer = sfTimerManager::getTimer('MediaWiki-style i18n');
        }
        
        if( !in_array( $text, $this->messages['en'] ) ) {
                $copy = array_keys( $this->messages['en'] );
                $recent = explode( '-', array_pop( $copy ) );
                
                if( count( $recent ) != 2 ) {
                        $recent = array( 'soxredtoolbase', 0 );
                }
                
                $this->messages['en'][ $recent[0] . '-' . ($recent[1] + 1) ] = $text;
                
                //file_put_contents( $this->filename, sprintf( "<?php\n\n\$messages = %s;", var_export( $this->messages, true ) ) );
                
                $key = $recent[0] . '-' . ($recent[1] + 1);
        }
        else {
                $key = array_search( $text, $this->messages['en'] );
        }
        
        if( isset( $this->messages[$this->culture][$key] ) ) {
                $message = $this->messages[$this->culture][$key];
        }
        else {
                $message = $this->messages['en'][$key];
        }
        
        
        if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled')) {
                $timer->addTime();
        }
        
        $message = $this->replaceArgs( sfToolkit::I18N_toUTF8( $message, 'UTF-8' ), $args );
        return sfToolkit::I18N_toEncoding( $message, 'UTF-8' );
        
  }
  
  public function listenToChangeCultureEvent(sfEvent $event)
  {
    // change the message format object with the new culture
    $this->setCulture($event['culture']);
  }
  
  /**
   * Sets the current culture for i18n format objects.
   *
   * @param string $culture The culture
   */
  public function setCulture($culture)
  {
    $this->culture = $culture;

    // change user locale for formatting, collation, and internal error messages
    setlocale(LC_ALL, 'en_US.utf8', 'en_US.UTF8', 'en_US.utf-8', 'en_US.UTF-8');
    setlocale(LC_COLLATE, $culture.'.utf8', $culture.'.UTF8', $culture.'.utf-8', $culture.'.UTF-8');
    setlocale(LC_CTYPE, $culture.'.utf8', $culture.'.UTF8', $culture.'.utf-8', $culture.'.UTF-8');
    setlocale(LC_MONETARY, $culture.'.utf8', $culture.'.UTF8', $culture.'.utf-8', $culture.'.UTF-8');
    setlocale(LC_TIME, $culture.'.utf8', $culture.'.UTF8', $culture.'.utf-8', $culture.'.UTF-8');

  }
  
  protected function replaceArgs($string, $args)
  {
    // replace object with strings
    foreach ($args as $key => $value)
    {
      if (is_object($value) && method_exists($value, '__toString'))
      {
        $args[$key] = $value->__toString();
      }
    }

    return strtr($string, $args);
  }
  
  public function getMessages() {
        return $this->messages;
  }
  
  
  public function i18n( $key /* ... */ ) {
        
        if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled')) {
                $timer = sfTimerManager::getTimer('MediaWiki-style i18n');
        }
        
        
        $params = func_get_args();
        array_shift( $params );
        if ( isset( $params[0] ) && is_array( $params[0] ) ) {
                $params = $params[0];
        }
        
        $params = array_values( $params );
        
        if( isset( $this->messages[$this->culture][$key] ) ) {
                $message = $this->messages[$this->culture][$key];
        }
        elseif( isset( $this->messages['en'][$key] ) ) {
                $message = $this->messages['en'][$key];
        }
        else {
                if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled')) {
                        $timer->addTime();
                }
                
                return "&lt;$key&gt;";
        }
        
        $replacementKeys = array();
        foreach( $params as $n => $param ) {
                $replacementKeys['$' . ($n + 1)] = $param;
        }
        $message = strtr( sfToolkit::I18N_toUTF8( $message, 'UTF-8' ), $replacementKeys );
        
        
        if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled')) {
                $timer->addTime();
        }
        
        return sfToolkit::I18N_toEncoding( $message, 'UTF-8' );
        
  }
        
}
